﻿

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LxCFD
{
    public partial class FvMesh : IPrepareMesh, IReset
    {
        public List<FvZone> Zones { get; set; } = new List<FvZone>();
        public List<FvContact> Contacts { get; set; } = new List<FvContact>();
        public bool IsTransient { get; set; } = false;
        public TransientTimeBase TransientTimeSetting = new TransientTimeFixed();
        public LinearSolverSetup LinearSolverSetting = new LinearSolverSetup();
        public class LinearSolverSetup
        {
            public int AMGGroupCount = 4;
            public int MaxCoarseLevel = 50;
            public bool IsBiCGOnlySupprotAMG = true;
        }

        public void PrepareMeshData()
        {
            ReMarkID();
            foreach (FvZone z in Zones)
            {
                z.PrepareMeshData();
            }
            foreach (var c in Contacts)
            {
                c.PrepareMeshData();
            }
            CreateAMGSolver();
            CreateBiCGSolver();
            //汇总输出
            foreach (var z in Zones)
            {
                LxConsole.Info(string.Format($"zone:{z.name},{z.TotalIndex},{z.InnerIndex}"));
                foreach (var t in z.BoundThreads)
                {
                    LxConsole.Info(string.Format($"thread:{t.name},{t.ThreadIndex}"));
                }
            }
        }
        public void ReMarkID()
        {
            int i = 0;
            foreach (var z in Zones)
            {
                z.ID = i;
                i++;
                int j = 0;
                foreach (var t in z.BoundThreads)
                {
                    t.ID = j;
                    j++;
                }
            }
            i = 0;
            foreach (var c in Contacts)
            {
                c.ID = i;
                i++;
            }
        }
        public void CreateFields()
        {
            AppRes.SolveCenter.IsTransient = IsTransient;
            if (IsTransient)
            {
                AppRes.SolveCenter.TransientTime = TransientTimeSetting.GetCopy();
            }
            foreach (var z in Zones)
            {
                z.CFDFields = new ZoneCFDFields();
                z.CFDFields.CheckCreate(z);
            }
            foreach (var c in Contacts)
            {
                c.CFDFields = new ContactCFDFields();
                c.CFDFields.SetParameter(c);
            }
        }

        public void Reset(ResetTypes clearType)
        {
            //switch (clearType)
            //{
            //    case ResetTypes.清除以加载新文件:
            //        break;
            //    case ResetTypes.清除以加载新网格:
            //        break;
            //    case ResetTypes.清空数据强制初始化:
            //    case ResetTypes.参数变更更新求解模块:
            //        AppRes.solveCenter.transientTime = transientTimeStore;////需要用copy
            //        AppRes.solveCenter.transientTime.Reset(clearType);
            //        break;
            //    case ResetTypes.不清空:
            //    default:
            //        break;
            //}
        }
        public void CreateAMGSolver()
        {
            if (Zones.Count <= 0) return;
            MGMeshCreator mgmaker = new MGMeshCreator();
            mgmaker.Create(LinearSolverSetting.MaxCoarseLevel, LinearSolverSetting.AMGGroupCount, Zones[0].Cells.Length);
            foreach (var z in Zones)
            {
                z.AMGSolver = new AMGInZone();
                z.AMGSolver.Create(mgmaker, z, z.Cells.Length, z.CellCommonArray);
            }
            foreach (var c in Contacts)
            {
                c.AMGSolver = new AMGInContact();
                c.AMGSolver.Create(c, mgmaker, c.OZone.AMGSolver, c.NZone.AMGSolver,
                    c.OThread.ID, c.NThread.ID);
            }
        }
        public void CreateBiCGSolver()
        {
            //创建BiCGStab
            foreach (FvZone z in Zones)
            {
                z.BiCGSolver = new BiCGStabInZone();
                z.BiCGSolver.CreateCommon(z.CellCommonArray, z.FaceCommonArray);
                z.AMGSolver.BiCGSolver = z.BiCGSolver;
            }
            foreach (var c in Contacts)
            {
                c.AMGSolver.O_BiCGSolver = c.O_BiCGSolver = c.OZone.BiCGSolver;
                c.AMGSolver.N_BiCGSolver = c.N_BiCGSolver = c.NZone.BiCGSolver;
            }
            if (LinearSolverSetting.IsBiCGOnlySupprotAMG)
            {
                foreach (FvZone z in Zones)
                {
                    z.BiCGSolver.CreateLocal(z.AMGSolver);
                }
            }
            else
            {
                foreach (FvZone z in Zones)
                {
                    z.BiCGSolver.CreateLocal(z);
                }
            }
        }
    }
}
